#include <func.h>
#include <time.h>
#include "BlockQ.h"
#include "HashMap.h"

// 服务端

int main(void)
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1)
        error(1, errno, "socket");

    struct sockaddr_in addr;
    addr.sin_port = htons(atoi("8080"));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    int reuse = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
        error(1, errno, "bind");

    if(listen(fd, 10) == -1)
        error(1, errno, "listen");

    int people = 0;
    struct man c_fd[50];
    /*
    BlockQ* q = blockq_create();
    HashMap* map = hashmap_create();
    */
    fd_set next_set;
    FD_ZERO(&next_set);
    FD_SET(fd, &next_set);
    while(1)
    {
        fd_set set = next_set;
        struct timeval timeout;
        timeout.tv_sec = 1; timeout.tv_usec = 0;
        if(select(20, &set, NULL, NULL, &timeout) == -1)
            error(1, errno, "select");

        if(FD_ISSET(fd, &set) && people != 50)
        {
            c_fd[people].fd = accept(fd, NULL ,NULL);
            FD_SET(c_fd[people].fd, &next_set);
            c_fd[people].alive = true;
            c_fd[people].time = time(NULL);
            people++;
            continue;
        }
        char buf[128] = {0};

        for(int i = 0; i < people; ++i)
        {
            if(FD_ISSET(c_fd[i].fd, &set) && c_fd[i].alive == true)
            {
                ssize_t err = recv(c_fd[i].fd, buf, 128, 0);
                switch(err)
                {
                case -1:
                    error(1, errno, "recv");    break;
                case 0:
                    FD_CLR(c_fd[i].fd, &next_set);
                    c_fd[i].alive = false;  break;
                default:
                    c_fd[i].time = time(NULL);
                    for(int j = 0; j < people; ++j)
                    {
                        if(c_fd[j].alive == true && i != j)
                            send(c_fd[j].fd, buf, 128, 0);
                    }
                }
            }
        }

        time_t current_time = time(NULL);
        for(int i = 0; i < people; ++i)
        {
            if(c_fd[i].alive == true && current_time - c_fd[i].time > 30)
            {
                FD_CLR(c_fd[i].fd, &next_set);
                c_fd[i].alive = false;
                close(c_fd[i].fd);
            }
        }
    }

    close(fd);
    return 0; 
}
